package com.jhf.youke.saga.client.annotation;


import cn.hutool.json.JSONUtil;
import com.jhf.youke.saga.client.domain.model.Do.SagaDo;
import com.jhf.youke.saga.client.domain.service.SagaClientService;
import lombok.extern.log4j.Log4j2;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Map;

/**
 *  针对ReadOnlyConnection注解进行切面编程
 *  @author RHJ
 *
 * **/
@Aspect
@Component
@Log4j2
public class SagaReplyInterceptor implements Ordered {

	@Resource
	private SagaClientService sagaClientService;


	@Around("@annotation(com.jhf.youke.saga.client.annotation.SagaReply)")
	public Object proceed(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
		log.info("begin saga reply");
		//获取注解参数值
		MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature();
		SagaReply sagaReply = methodSignature.getMethod().getAnnotation(SagaReply.class);
		String abnormal = sagaReply.abnormal();

		Object[] args = proceedingJoinPoint.getArgs();
		String json = JSONUtil.toJsonStr(args[0]);
		Map<String, Object> map = JSONUtil.toBean(json, Map.class);
		if(map != null) {
			// 将saga服务保存到本地
			sagaClientService.createMsg(map);
			sagaClientService.create(map);
		}
		Object result;
		//原有方法执行完毕
		try {
			 result = proceedingJoinPoint.proceed();
		}catch (Exception e){
			// 业务消费进行失败处理
			SagaDo sagaDo = new SagaDo(map);
			SagaDo saga = sagaClientService.getByBiz(sagaDo.getCode(),sagaDo.getBizId(),sagaDo.getObjectId(),sagaDo.getSort());
			sagaClientService.fail(saga, abnormal);
			log.info("消费失败 {}", e.getMessage());
			return null;
		}

		if(map != null) {
			SagaDo sagaDo = new SagaDo(map);
			sagaClientService.ok(sagaDo);
			// 消费成功，对saga服务进行应答
			try {
				sagaClientService.reply(sagaDo,abnormal);
			}catch (Exception e){
				SagaDo saga = sagaClientService.getByBiz(sagaDo.getCode(),sagaDo.getBizId(),sagaDo.getObjectId(),sagaDo.getSort());
				sagaClientService.replyFail(saga,abnormal);
				e.printStackTrace();
				return null;
			}
			log.info("saga reply ok");
		}
		return result;
	}

	@AfterThrowing(pointcut="execution(* com.jhf.youke.*.*(..)))",throwing="e")
	public void afterThrowing(JoinPoint joinPoint, Throwable  e) throws Throwable {
		log.info("business is error begin handler {}", e.getMessage());
		log.info("请求类方法:"+ joinPoint.getSignature().getName());
//		Object[] args = proceedingJoinPoint.getArgs();
//		String json = JSONUtil.toJsonStr(args[0]);
//		Map<String, Object> map = JSONUtil.toBean(json, Map.class);
//		if(map != null) {
//			SagaDo sagaDo = new SagaDo(map);
//			//获取注解参数值
//			MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature();
//			SagaReply sagaReply = methodSignature.getMethod().getAnnotation(SagaReply.class);
//			String abnormal = sagaReply.abnormal();
//			sagaClientService.fail(sagaDo, abnormal);
//			log.info("business is error handler end");
//		}

	}

	@Override
	public int getOrder() {
		return 0;
	}


}